package org.mili.ticketeer.dao;

import org.mili.application.dao.AbstractDao;
import org.mili.application.dao.DaoException;
import org.mili.application.dao.ModificationResult;
import org.mili.application.dao.RowTransformer;
import org.mili.application.dao.query.QueryBuilder;
import org.mili.application.dto.Identifieable;
import org.mili.ticketeer.dto.Role;
import org.mili.application.util.Lambda;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

public class RoleDao extends AbstractDao {

    public RoleDao() {
        super(Role.UniqueFields.values(), Role.Fields.values(), Role.TABLE);
    }

    public List<Role> getRoles() throws DaoException {
        return read(new RoleRowTransformer());
    }

    public ModificationResult write(final Role role) throws DaoException {
        return createOrUpdate(role);
    }

    public Role findById(final int id) throws DaoException {
        return doInDao(new Lambda<Role>() {
            @Override
            public Role exec(Object... params) throws SQLException {
                return querySingle(new RowTransformer<Role>() {
                    @Override
                    public Role transform(ResultSet resultSet) throws SQLException {
                        Role role = new Role();
                        role.setId(id);
                        role.setName(resultSet.getString(Role.Fields.NAME.name()));
                        return role;
                    }
                },
                QueryBuilder.createQueryBuilder()
                        .select()
                        .fields(Role.Fields.NAME)
                        .from(table)
                        .where()
                        .eq(Identifieable.Fields.ID, id).build());
            }
        });
    }

    public Role findByName(final String name) throws DaoException {
        return doInDao(new Lambda<Role>() {
            @Override
            public Role exec(Object... params) throws SQLException {
                return querySingle(new RowTransformer<Role>() {
                    @Override
                    public Role transform(ResultSet resultSet) throws SQLException {
                        Role role = new Role();
                        role.setId(resultSet.getInt(Identifieable.Fields.ID.name()));
                        role.setName(name);
                        return role;
                    }
                },
                    QueryBuilder.createQueryBuilder()
                            .select()
                            .fields(Identifieable.Fields.ID)
                            .from(table)
                            .where()
                            .eq(Role.Fields.NAME, name).build());
            }
        });
    }

    class RoleRowTransformer implements RowTransformer<Role> {
        @Override
        public Role transform(ResultSet resultSet) throws SQLException {
            Role role = new Role();
            role.setId(resultSet.getInt(Identifieable.Fields.ID.name()));
            role.setName(resultSet.getString(Role.Fields.NAME.name()));
            return role;
        }
    }
}
